﻿using System.Collections.Generic;

namespace Xfs
{
	[XfsObjectSystem]
	public class XfsLockInfoAwakeSystem : XfsAwakeSystem<XfsLockInfo, long, CoroutineLock>
	{
		public override void Awake(XfsLockInfo self, long lockInstanceId, CoroutineLock coroutineLock)
		{
			self.LockInstanceId = lockInstanceId;
			self.CoroutineLock = coroutineLock;
		}
	}
		
	
	public class XfsLocationComponent : XfsComponent
	{
		public static XfsLocationComponent Instance;

		public long inId;



		private readonly Dictionary<long, long> locations = new Dictionary<long, long>();

		private readonly Dictionary<long, XfsLockInfo> lockInfos = new Dictionary<long, XfsLockInfo>();
		


		public XfsLocationComponent()
        {
			Instance = this;
        }
		public override void Dispose()
		{
			if (this.IsDisposed)
			{
				return;
			}
			
			base.Dispose();
			
			this.locations.Clear();

			foreach (XfsLockInfo lockInfo in this.lockInfos.Values)
			{
				lockInfo.Dispose();
			}
			
			this.lockInfos.Clear();
		}

		public async XfsTask Add(long key, long instanceId)
		{
			using (await XfsCoroutineLockComponent.Instance.Wait(key + (int)XfsAppType.XfsLocation))
			{
				this.locations[key] = instanceId;
				//Log.Info($"location add key: {key} instanceId: {instanceId}");
			}
		}

		public async XfsTask Remove(long key)
		{
			using (await XfsCoroutineLockComponent.Instance.Wait(key + (int)XfsAppType.XfsLocation))
			{
				this.locations.Remove(key);
				//Log.Info($"location remove key: {key}");
			}
		}

		//public async XfsTask<long> Get(long key)
		//{
		//	using (await XfsCoroutineLockComponent.Instance.Wait(key + (int)XfsAppType.XfsLocation))
		//	{
		//		this.locations.TryGetValue(key, out long instanceId);
		//		//Log.Info($"location get key: {key} {instanceId}");
		//		return instanceId;
		//	}

		//}

		public async XfsTask Lock(long key, long instanceId, int time = 0)
		{
			if (!this.locations.TryGetValue(key, out long saveInstanceId))
			{
				//Log.Error($"actor没有注册, key: {key} InstanceId: {instanceId}");
				return;
			}
			
			if (saveInstanceId != instanceId)
			{
				//Log.Error($"actor注册的instanceId与lock的不一致, key: {key} InstanceId: {instanceId} saveInstanceId: {saveInstanceId}");
				return;
			}
			
			CoroutineLock coroutineLock = await XfsCoroutineLockComponent.Instance.Wait(key + (int)XfsAppType.XfsLocation);

			XfsLockInfo lockInfo = XfsComponentFactory.Create<XfsLockInfo, long, CoroutineLock>(instanceId, coroutineLock);
			
			this.lockInfos.Add(key, lockInfo);
			
			//Log.Info($"location lock key: {key} InstanceId: {instanceId}");

			// 超时则解锁
			if (time > 0)
			{
				await XfsGame.XfsSence.GetComponent<XfsTimerComponent>().WaitAsync(time);
				this.UnLock(key, instanceId, instanceId);
			}
		}

		public void UnLock(long key, long oldInstanceId, long newInstanceId)
		{
			if (!this.lockInfos.TryGetValue(key, out XfsLockInfo lockInfo))
			{
				return;
			}
			if (lockInfo.LockInstanceId != oldInstanceId)
			{
				//Log.Error($"unlock appid is different {lockInfo.LockInstanceId} {oldInstanceId}" );
				return;
			}
			//Log.Info($"location unlock key: {key} oldInstanceId: {oldInstanceId} new: {newInstanceId}");
			
			this.locations[key] = newInstanceId;
			lockInfo.Dispose();
		}
	}
}